/*
  1 获取用户的收货地址
    ① 绑定点击事件
    ② 调用小程序内置 api 获取用户的收货地址(wx.chooseAddress)
    ③ 获取用户对小程序所授予“获取地址的权限状态”(scope)
      Ⅰ 假设用户点击确定（获取收货地址的提示框），则 authSetting.["scope.address"]值为 true
      Ⅱ 假设用户从来没有调用过收货地址的api，则 authSetting.["scope.address"] 为 undefined
      注：前两种情况都可以直接调用“获取收货地址”，而第三种不行，故须特殊处理
      Ⅲ 假设用户点击取消（获取收货地址的提示框），则 authSetting.["scope.address"]值为 false
        ① 诱导用户自己打开授权设置页面(wx.openSetting) 让用户重新给予获取地址权限
        ② 获取收货地址
      Ⅳ 把获取到的收货地址存入到本地存储中
  2 页面加载完毕(因为每次打开该页面，数据都要重置，故此处用onShow)
    ① 获取本地存储中的地址数据
    ② 把数据设置给 data 中的一个变量
  3 onShow
    ① 在商品详情页面第一次添加商品的时候，手动添加了两个属性
      Ⅰ num = 1;
      Ⅱ checked = true;
    ② 获取缓存中的购物车数组
    ③ 把购物车数据填充到 data 中
  4 全选的实现 数据的展示
    ① 在 onShow 中获取缓存中的购物车数组并进行判断
    ② 根据购物车中的商品数据判断（所有的商品都被选中则“全选”被选中）
  5 总价格和总数量（计算被选中的商品）
    ① 获取购物车数组
    ② 遍历判断商品是否被选中
    ③ 总价格 += 商品的单价 * 商品的数量
    ④ 总数量 += 商品的数量
    ⑤ 将计算后的价格和数量设置到 data 中
  6 购物车中商品的选中与否（影响着全选与否以及总价格数量等）
    ① 绑定 change事件
    ② 获取到被修改的商品对象
    ③ 商品对象的选中状态取反（AppData和缓存中的数据都需要修改）
    ④ 重新填充回 data 和缓存中
    ⑤ 重新计算是否全选，总价格以及总数量
  7 底部工具栏全选框的全选与反选
    ① 全选复选框绑定事件 change
    ② 获取 data数据中的全选属性
    ③ 直接取反 allChecked = !allChecked
    ④ 遍历购物车数组 让里面商品的选中状态跟随 allChecked 的改变而改变
    ⑤ 把购物车数据和 allChecked 重新设置回 data中，把购物车数据设置回缓存中
  8 商品数量的编辑功能
    ① “+”和“-”按钮绑定同一个点击事件，用自义定属性(data-operation)来区分两者
    ② 传递被点击的商品id（goods_id）
    ③ 获取 data 中的购物车数组，来获取需要被修改的商品对象
    ④ 直接修改商品对象的数量num
      Ⅰ 若修改后，商品数量大于0，则正常进行操作
      Ⅱ 若修改后，商品数量等于0，则询问用户是否要删除商品（wx.showModal(Object object)）
        壹 若点击确定，则直接执行删除操作
        贰 若点击取消，则什么都不做（不修改商品数量）
    ⑤ 把 cart数组重新设置回缓存和 data 中（用this.setCart方法）
  9 点击结算按钮
    ① 判断有没有收货地址信息
    ② 判断用户有没有选购商品
    ③ 经过以上的验证，跳转到支付页面
*/

import { getSetting, chooseAddress, openSetting, showModal, showToast} from "../../utils/asyncWx.js"
import regeneratorRuntime from '../../lib/runtime/runtime';

Page({

  /**
   * 页面的初始数据
   */
  data: {
    address: {},
    cart: [],
    allChecked: false,
    totalPrice: 0,
    totalNum: 0
  },

  onShow() {
    // 1.1 获取缓存中的收货地址信息
    const address = wx.getStorageSync('address');
    // console.log(address);
    // 1.2 获取缓存中的购物车数据
    const cart = wx.getStorageSync('cart') || [];
    // console.log(cart);

    // 1.3 计算全选
    // every数组方法：接收一个回调函数，每一个回调函数都返回true，则其返回值为true
    //               若有一个回调函数返回false，则不再执行循环，直接返回false
    // 注意：空数组调用 every，返回值也是true
    // 考虑到性能问题，将该操作合并到 1.4 中
    // const allChecked = cart.length ? cart.every(v => v.checked) : false;

    this.setData({address});
    this.setCart(cart);
    // let allChecked = true;
    // // 1.4 计算总价格和总数量
    // let totalPrice = 0;
    // let totalNum = 0;
    // cart.forEach(v => {
    //   if (v.checked) {
    //     totalPrice += v.num * v.goods_price;
    //     totalNum += v.num;
    //   } else {
    //     allChecked = false;
    //   }
    // })
    // // 判断数组是否为空(若为空则上面操作不会执行，allChecked为true)
    // allChecked = cart.length != 0 ? allChecked : false;
    // // 2 给 data 赋值
    // this.setData({
    //   address,
    //   cart,
    //   allChecked,
    //   totalPrice,
    //   totalNum
    // })
  },

  // 点击收货地址
  handleChooseAddress() {
    wx.chooseAddress({
      success: (address) => {
        // console.log(address);
        address.all = address.provinceName + address.cityName
        + address.countyName + address.detailInfo;
        wx.setStorageSync('address', address);
      },
    })
  },

  // 旧版本的写法（新版本已经更新了这个bug）
  // handleChooseAddress() {
  //   // 获取权限状态
  //   wx.getSetting({
  //     success: (res) => {
  //       // 获取权限状态（发现一些属性名很怪异的时候 要使用 [] 的形式来获取属性值）
  //       const scopeAddress = res.authSetting['scope.address'];
  //       if (scopeAddress === true || scopeAddress === undefined) {
  //         // 获取收货地址
  //         wx.chooseAddress({
  //           success: (res1) => {
  //             console.log(res1);
  //           },
  //         });
  //       } else {
  //         // 用户以前拒绝过授予权限 先诱导用户打开授权页面
  //         wx.openSetting({
  //           success: (res2) => {
  //             // 调用获取收获地址代码
  //             wx.chooseAddress({
  //               success: (res1) => {
  //                 console.log(res1);
  //               },
  //             });
  //           },
  //         })
  //       }
  //     },
  //   })
  // }

  // // 对上面代码的简化
  // async handleChooseAddress() {
  // // 1 获取权限状态
  // const res1 = await getSetting();
  // const scopeAddress = res1.authSetting['scope.address'];
  // // 2 判断权限状态
  // if (scopeAddress === true || scopeAddress === undefined) {
  //   // 3 调用获取收货地址的 api
  //   const res2 = await chooseAddress();
  //   console.log(res2);
  // } else {
  //   // 3 先诱导用户打开授权页面
  //   await openSetting();
  //   // 4 调用获取收货地址的 api
  //   const res2 = await chooseAddress();
  //   console.log(res2);
  // }
  // }

  // // 对上面代码的进一步简化
  // async handleChooseAddress() {
  //   // 1 获取权限状态
  //   const res1 = await getSetting();
  //   const scopeAddress = res1.authSetting['scope.address'];
  //   // 2 判断权限状态
  //   if (scopeAddress === false) {
  //     await openSetting();
  //   }
  //   // 4 调用获取收货地址的 api
  //   const res2 = await chooseAddress();
  //   console.log(res2);
  //   }

  // // 还需进行错误处理 并把把获取到的收货地址存入到本地存储中
  // async handleChooseAddress() {
  // try {
  //   // 1 获取权限状态
  //   const res1 = await getSetting();
  //   const scopeAddress = res1.authSetting['scope.address'];
  //   // 2 判断权限状态
  //   if (scopeAddress === false) {
  //     await openSetting();
  //   }
  //   // 4 调用获取收货地址的 api
  //   const address = await chooseAddress();
  //   // 5 存入到缓存中
  //   wx.setStorageSync('address', address);
  //   }
  //  catch (error) {
  //   console.log(err);
  //   }
  // }

  // 商品的选中
  handleItemChange(e) {
    // 1 获取被修改的商品的id
    const goods_id = e.currentTarget.dataset.id;
    // console.log(goods_id);
    // 2 获取购物车数组
    let {cart} = this.data;
    // 3 找到被修改的商品对象
    let index = cart.findIndex(v => v.goods_id === goods_id);
    // 4 选中状态取反
    cart[index].checked = !cart[index].checked;

    this.setCart(cart);
    // // 5 通过已经更新的数据修改“全选”、“总价格”和“总数量”属性
    // let allChecked = true;
    // // 计算总价格和总数量
    // let totalPrice = 0;
    // let totalNum = 0;
    // cart.forEach(v => {
    //   if (v.checked) {
    //     totalPrice += v.num * v.goods_price;
    //     totalNum += v.num;
    //   } else {
    //     allChecked = false;
    //   }
    // })
    // // 判断数组是否为空(若为空则上面操作不会执行，allChecked为true)
    // allChecked = cart.length != 0 ? allChecked : false;

    // // 6 把购物车数据重新设置并返回 缓存 中
    // wx.setStorageSync('cart', cart);
    // // 7 把更新后的购物车数据返回 data 中
    // this.setData({
    //   cart,
    //   allChecked,
    //   totalPrice,
    //   totalNum
    // });
    
  },

  // 设置购物车状态的同时，重新计算底部工具栏的数据（全选、总价格、总数量）
  setCart(cart) {
    // 通过已经更新的缓存数据修改“全选”、“总价格”和“总数量”属性
    let allChecked = true;
    // 计算总价格和总数量
    let totalPrice = 0;
    let totalNum = 0;
    cart.forEach(v => {
      if (v.checked) {
        totalPrice += v.num * v.goods_price;
        totalNum += v.num;
      } else {
        allChecked = false;
      }
    })
    // 判断数组是否为空(若为空则上面操作不会执行，allChecked为true)
    allChecked = cart.length != 0 ? allChecked : false;

    // 把更新后的购物车数据返回 data 和缓存中
    this.setData({
      cart,
      allChecked,
      totalPrice,
      totalNum
    });
    wx.setStorageSync('cart', cart);
  },

  // 商品的全选功能
  handleItemAllCheck() {
    // 1 获取data中的数据
    let {cart, allChecked} = this.data;
    // 2 修改值
    allChecked = !allChecked;
    // 3 循环修改 cart数组中的商品的选中状态(Checked属性)
    cart.forEach(v => v.checked = allChecked);
    // 4 把修改后的值填充回 data 与缓存中
    this.setCart(cart);
  },

  // 商品数量的编辑功能
  async handleItemNumEdit(e) {
    // 1 获取传递过来的参数
    const {operation, index} = e.currentTarget.dataset;
    // console.log(operation, id);
    // 2 获取购物车数组
    let {cart} = this.data;
    // 3 判断是否要执行删除操作
    if (cart[index].num === 1 && operation === -1) {
      
      // 3.1 弹窗提示
      // wx.showModal({
      //   title: '提示',
      //   content: '是否删除当前商品？',
      //   // 箭头函数中的 this 会往外部找
      //   success: (res) => {
      //     if (res.confirm) {
      //       cart.splice(index, 1);
      //       this.setCart(cart);
      //     } else if (res.cancel) {
      //       console.log('用户点击取消')
      //     }
      //   }
      // })
      
      // 对以上代码的简化
      const res = await showModal({content: '是否删除当前商品？'});
      if (res.confirm) {
        cart.splice(index, 1);
        this.setCart(cart);
      }
    } else {
      // 进行数量的修改
      cart[index].num += operation;
      // 设置回缓存和 data 中
      this.setCart(cart);
    }
  },

  // 点击结算按钮
  async handlePay() {
    const {address, totalNum} = this.data;
    // 1 判断收货地址
    if (!address.userName) {
      await showToast({title:"请选择收货地址！"});
      return;
    }
    // 2 判断用户有没有选购商品
    if (totalNum === 0) {
      await showToast({title:"请选购商品！"});
      return;
    }
    // 3 跳转到支付页面
    wx.navigateTo({
      url: '/pages/pay/index'
    }); 
  }
})